#include <stdlib.h>
#include "app_device.h"
#include "../thirdparty/log.h"
#include "../app/app_mqtt.h"
#include "../app/app_pool.h"
#include "../app/app_message.h"
#include "../app/app_Common.h"
/**
 * @brief 设备初始化函数
 *
 * @return app_dev_t* 创建的设备的句柄
 */
app_dev_t *App_device_Init(void)
{
    /*1.创建设备*/
    app_dev_t *dev = (app_dev_t *)malloc(sizeof(app_dev_t) * 1);
    if (dev == NULL)
    {
        log_error("memory malloc fail\n");
        return NULL;
    }
    /*2.配置设备文件名并打开设备文件*/
    dev->file_name = DEV_FILE_NAME;
    dev->dev_fd = open(DEV_FILE_NAME, O_RDWR | O_APPEND, 0664);
    if (dev->dev_fd == -1)
    {
        perror("file open fail\n");
    }
    /*3.初始化其他参数*/
    dev->read_pthread = -1;
    dev->post_read = NULL;
    dev->pre_write = NULL;
    /*4.创建上下行缓冲区*/
    dev->up_buff = App_buffer_Init();
    dev->down_buff = App_buffer_Init();
    if (dev->down_buff == NULL || dev->up_buff == NULL)
    {
        log_error("craet up/down fail\n");
    }
    /*5.返回设备句柄*/
    return dev;
}

/*数据上行流程2*/
static void *App_device_up_2(void *args)
{
    app_dev_t *dev_p = (app_dev_t *)args;
    /*1.从缓冲区中读取数据*/
    char *json_buff;
    char read_buff[100];
    int data_len = 0;
    data_len = App_buffer_Read(dev_p->up_buff, read_buff, 100);
    if (data_len == -1)
    {
        log_error("[up_2]->read buff fail\n");
        return NULL;
    }
    /*2.将数据转换为json字符串格式*/
    App_Message_bytes_to_json(&json_buff, read_buff, 100);
    /*2.通过mqtt将数据发送至外网*/
    App_mqtt_SendMsg(json_buff, strlen(json_buff));
    /*3.释放json_buff指向的cjson字符串占用的内存*/
    free(json_buff);
    return NULL;
}

/*数据上行流程1*/
static void *App_device_up_1(void *args)
{
    int read_size;       // 实际读取到的俄数据长度
    char read_buff[100]; // 读取数据的临时缓冲区
    /*拿到设备文件描述符*/
    app_dev_t *dev_p = (app_dev_t *)args;
    while (1)
    {
        /*1.读取设备文件中的数据*/
        read_size = read(dev_p->dev_fd, read_buff, 100);
        /*2.根据读取情况执行相应逻辑*/
        if (read_size == -1) // 读取失败
        {
            perror("[up_1]->read from file fail\n");
            continue;
        }
        if (read_size > 0) // 读取到数据
        {
            /*3.对数据进行预处理*/
            if (dev_p->post_read != NULL)
            {
                read_size = dev_p->post_read(read_buff, read_size);
            }

            /*4.将数据写进上行缓冲区*/
            if (read_size > 0)
            {
                App_Common_Printf_Bytes(read_buff, read_size); // 将数据打印一下便于调试
                int res = App_buffer_Write(dev_p->up_buff, read_buff, read_size);
                if (res == -1)
                {
                    log_error("[up_1]->write buffer fail\n");
                    continue;
                }
                /*5.向线程池提交任务*/
                res = App_pool_Submit_Task(App_device_up_2, dev_p);
                if (res == -1)
                {
                    log_error("[up_1]->submit task to mqueue fail\n");
                }
            }
        }
    }
    return NULL;
}

/*数据下行流程2*/
static void *App_device_down_2(void *args)
{
    app_dev_t *dev_p = (app_dev_t *)args;
    char read_buff[100];
    int read_size = 0;
    /*1.从缓冲区中读数据*/
    read_size = App_buffer_Read(dev_p->down_buff, read_buff, 100);
    if (read_size == -1)
    {
        log_error("[down_2]->read buffer fail\n");
        return NULL;
    }
    App_Common_Printf_Bytes(read_buff, read_size); // 将读到的数据打印便于调试
    /*2.将数据进行预处理*/
    if (dev_p->pre_write != NULL)
    {
        read_size = dev_p->pre_write(read_buff, read_size);
    }
    log_info("%.*s\n",read_size,read_buff);
    /*3.将处理后的数据写进设备文件*/
    int write_size = write(dev_p->dev_fd, read_buff, read_size);
    if (write_size != read_size)
    {
        log_error("[down_2]->write to file fail\n");
    }
    return NULL;
}

/*数据下行流程1*/
static int App_device_down_1(void *args, char *data, int len)
{
    app_dev_t *dev_p = (app_dev_t *)args;
    /*1.将json字符串转换成字符数组格式*/
    char bytes_buff[100];
    int bytes_len = 0;
    App_Message_json_to_bytes(data, bytes_buff, &bytes_len);
    /*2.将数据写入下行缓冲区内*/
    int res = App_buffer_Write(dev_p->down_buff, bytes_buff, bytes_len);
    if (res == -1)
    {
        log_error("[down_1]->write buffer fail\n");
        return -1;
    }
    /*3.向线程池提交任务*/
    res = App_pool_Submit_Task(App_device_down_2, dev_p);
    if (res == -1)
    {
        log_error("[down_1]->submit task to mqueue fail\n");
        return -1;
    }
    return 0;
}
/**
 * @brief 设备启动函数
 *
 * @param dev 设备句柄
 * @return int 成功返回0 失败返回-1
 */
int App_device_Start(app_dev_t *dev)
{
    /*1.创建设备文件读线程*/
    int res = pthread_create(&dev->read_pthread, NULL, App_device_up_1, dev);
    if (res == -1)
    {
        perror("dev read_pthread creat fail\n");
        return -1;
    }
    /*2.注册mqtt消息到达事件的回调函数*/
    App_mqtt_Register_Callback(dev, App_device_down_1);
    /*3,返回设备启动结果*/
    return 0;
}

/**
 * @brief 销毁设备函数
 *
 * @param dev 设备句柄
 */
void App_device_destroy(app_dev_t *dev)
{
    /*1.销毁设备文件的读线程*/
    pthread_cancel(dev->read_pthread);
    /*销毁上下行缓冲区*/
    App_buffer_destroy(dev->down_buff);
    App_buffer_destroy(dev->up_buff);
    /*2.注销mqtt模块数据到达事件的回调函数*/
    App_mqtt_Register_Callback(NULL, NULL);
    /*3.关闭设备文件*/
    close(dev->dev_fd);
    /*4.释放设备结构体内存*/
    free(dev);
}
